#include "Lrc.h"
#include <fstream>
#include <string>
#include <sstream>
#include <algorithm>
#include <functional>
#include "CharsetConvert.h"

using namespace std;


CLrc::CLrc(void)
{

}

CLrc::~CLrc(void)
{

}

void CLrc::SetLrcFile(const std::string &file)
{

	ifstream inlrc(file.c_str());
	if (inlrc.fail())
	{
		m_lrcMap.clear();
		m_lrcMap.push_back(make_pair(0, "open file failed!"));
		return;
	}

	string encode = CCharsetConvert::GetIns().DetectEncode(file);
	if (encode == "utf-16" || encode == "utf-16le")
	{
		string str = CCharsetConvert::GetIns().ConvertUTF16ToUTF8(file);
		istringstream stream(str);
		CCharsetConvert::GetIns().SetFileEncode("utf8");
		Parse(stream);
	}
	else if (encode != "unknown")
	{
		CCharsetConvert::GetIns().SetFileEncode(encode);
		Parse(inlrc);
	}
	else
		Parse(inlrc);
}

std::string CLrc::GetLrcString(size_t time)
{
	if (m_lrcMap.empty())
	{
		return "m_lrcMap.empty()";
	}

	LrcMap::iterator iter = find_if(m_lrcMap.begin(), m_lrcMap.end(), 
		bind2nd(greater<pair<size_t, string> >(), make_pair(time + m_offset, "")));

	if (iter != m_lrcMap.begin())
	{
		return (--iter)->second;
	}
	return iter->second;
}

void CLrc::Parse(istream& in)
{
	m_lrcMap.clear();
	m_offset = 0;

	string line;
	while(getline(in, line))
	{
		if (isdigit(line[1]))
		{
			string::size_type time_end = line.find_last_of(']');
			if (time_end == string::npos)
			{
				//bad line, read the next line
				continue;
			}

			string realLrc;
			if (time_end == line.size())
				realLrc = "";
			else
				realLrc = line.substr(++time_end);

			string::size_type time_begin = line.find('[');
			while ( (time_end = line.find(']', time_begin)) != string::npos)
			{
				istringstream lrctime(line.substr(time_begin, time_end - time_begin));
				size_t minute;
				float second;
				char tmp;
				// [mm:ss.xx 
				lrctime >> tmp >> minute >> tmp >> second;
				size_t time = (minute * 60 + second) * 1000;	// ms
				m_lrcMap.push_back(make_pair(time, realLrc));

				time_begin = time_end + 1;
			}
		}
		// [offset:500]
		else if (line.substr(0, 7) == "[offset")
		{
			istringstream offsetText(line.substr(8));
			offsetText >> m_offset;
		}
	}

	sort(m_lrcMap.begin(), m_lrcMap.end());
}

